package com.syqc.videos

import android.Manifest
import android.content.Intent
import android.view.Gravity
import android.view.KeyEvent
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.recyclerview.widget.GridLayoutManager
import autodispose2.autoDispose
import com.gyf.immersionbar.ktx.immersionBar
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.permissionx.guolindev.PermissionX
import com.syqc.base.BaseRealFragment
import com.syqc.choose.car.ChooseCarActivity
import com.syqc.choose.teamcar.TeamsCarsActivity
import com.syqc.comlib.AppConfigs
import com.syqc.comlib.UserConstant
import com.syqc.comlib.base.BaseActivity
import com.syqc.comlib.callback.EmptyCallback
import com.syqc.comlib.rx.LiveDataBus
import com.syqc.comlib.rx.filterFast
import com.syqc.comlib.utils.ActivityResultUtil.launchAct
import com.syqc.comlib.utils.ActivityResultUtil.registerResultOk
import com.syqc.comlib.utils.ToolbarHelper
import com.syqc.comlib.utils.toast
import com.syqc.monitor.R
import com.syqc.monitor.databinding.ActivityRealVideoBinding
import com.syqc.utils.Keys
import com.syqc.utils.NetDataUtil
import com.syqc.utils.ToolsUtil
import com.syqc.utils.VideoHostUtil
import com.syqc.videos.real.ChannelFragment
import com.syqc.videos.real.ControllerFragment
import com.syqc.videos.real.SettingFragment
import com.syqc.videos.real.TalkFragment
import com.syqc.videos.real.VideoAlarmFragment
import com.syqc.videos.videomanager.PlayerManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers


abstract class BasePlayerActivity :
    BaseActivity<ActivityRealVideoBinding>(ActivityRealVideoBinding::inflate) {
    private var mTextView: TextView? = null
    private val mViewModel by viewModels<com.syqc.videos.RealPlayerVM>()
    private val mAdapter: com.syqc.videos.RealPlayerAdapter by lazy {
        com.syqc.videos.RealPlayerAdapter(
            UserConstant.current_userId
        )
    }
    private var loadService: LoadService<Any>? = null
    private val alarmFrag by lazy { VideoAlarmFragment(2) }
    private val ctrlFrag by lazy { ControllerFragment(3) }
    private val settingFrag by lazy {
        SettingFragment(
            typeCallback = { type ->
                mAdapter.playerMap.values.forEach {
                    it.changVideoType(type)
                }
            },
            streamCallback = { stream ->
                mAdapter.playerMap.values.forEachIndexed { index, realPlayer ->
                    mAdapter.changeStreamOrClose(mAdapter.data[index], realPlayer, stream)
                }
            })
    }
    private val talkFrag by lazy {
        TalkFragment(0) {
            binding.container.isVisible = false
            binding.ivClose.isVisible = false
            oldType = -1
            binding.tvTalk.isSelected = false
        }
    }
    private val channelFrag by lazy {
        ChannelFragment(4) {
            val data = it.filter { it.isChecked }
            mAdapter.setList(null)
            mAdapter.clearPlayer()
            PlayerManager.clearAllVideo()
            if (data.size > 3) {
                manager?.spanCount = 2
            } else {
                manager?.spanCount = 1
            }
            mAdapter.setList(data)

        }
    }

    //正在展示的
    private var showType = -1
    private var oldType = -1
    private var oldTextView: TextView? = null

    private val menuPopup by lazy {
        com.syqc.videos.OperaMenuPopup(this)
    }

    private val operaPopup by lazy {
        com.syqc.videos.OperaPopup(this) {
            when (it.id) {
                R.id.tvTalk -> {
                    if (mViewModel.isParamsOk()) return@OperaPopup
                    if (mViewModel.getAudioPass().isEmpty()) return@OperaPopup
                    showType = 0

                    getPermissions(binding.tvTalk)
                }

                R.id.tvDevice -> {
                    if (mViewModel.isParamsOk()) return@OperaPopup
                    showType = 2

                    showFragment(showType, binding.tvDevice)

                }

                R.id.tvCloud -> {
                    if (mViewModel.isParamsOk()) return@OperaPopup
                    showType = 3

                    showFragment(showType, binding.tvController)
                }

                R.id.tvPass -> {
                    if (mViewModel.isParamsOk()) return@OperaPopup
                    showType = 4

                    showFragment(showType, binding.tvChannel)
                }

                R.id.tvSet -> {
                    if (mViewModel.isParamsOk()) return@OperaPopup
                    showType = 5

                    showFragment(showType, binding.tvSetting)
                }

                R.id.tvMap -> {
                    if (mViewModel.isChooseCar()) return@OperaPopup
                    showType = 1
                    showFragment(showType, binding.tvMap)
                }
            }
        }
    }


    override fun initView() {
        initToolbar()
        initLoadSir()
        initRecycler()
        initViewModel()
        initIntent()
        if (mViewModel.isShowPopup) {
            mViewModel.isShowPopup = false

            binding.root.postDelayed({
                menuPopup.showAtLocation(binding.root, Gravity.NO_GRAVITY, 0, 0)
            }, 300)
        }
        binding.sIvOpera.isVisible = AppConfigs.isMenuFloat
        binding.llBottom.isVisible = !AppConfigs.isMenuFloat
    }

    private fun initViewModel() {
        mViewModel.toastObserver().observeOn(AndroidSchedulers.mainThread())
            .autoDispose(scopeProvider).subscribe(this::toastObserver)
        mViewModel.passLive.observe(this) {
            if (it.size > 3) {
                manager?.spanCount = 2
            } else {
                manager?.spanCount = 1
            }
            channelFrag.setChannels(it)
            mAdapter.setList(it)
            if (it.isNullOrEmpty()) {
                loadService?.showCallback(EmptyCallback::class.java)
            } else {
                loadService?.showSuccess()
            }
        }

        //切换通道监听
        LiveDataBus.get().with("RealPass", String::class.java).observe(this) {
            mViewModel.controlPass = it
            mViewModel.setAudioPass(it)

        }
    }


    override fun setListener() {
        binding.sIvOpera.setOnLongClickListener {
            it.parent.requestDisallowInterceptTouchEvent(true)
            return@setOnLongClickListener true
        }

        binding.sIvOpera.setOnClickListener {
            binding.sIvOpera.isInvisible = true
            operaPopup.showAtLocation(binding.root, Gravity.CENTER, 0, 0)
        }
        operaPopup.setOnDismissListener {
            binding.sIvOpera.isInvisible = false
        }

        //选车
        binding.lrvChooseCar.filterFast {
            if (NetDataUtil.isSyncTree) {
                launcher.launchAct<TeamsCarsActivity>(this) {
                    putExtra(Keys.INTENT_IS_VIDEO, true)
                }
            } else {
                launcher.launchAct<ChooseCarActivity>(this) {
                    putExtra(Keys.INTENT_IS_VIDEO, true)
                }
            }
            binding.tvSetting.postDelayed({
                resetCar()
                com.syqc.videos.TalkbackUtil.destroy()
                currentFragment?.hide()
                oldTextView?.isSelected = false
                binding.container.isVisible = false
                binding.ivClose.isVisible = false
            }, 100)

        }

        binding.tvTalk.filterFast {
            if (mViewModel.isParamsOk()) return@filterFast
            if (mViewModel.getAudioPass().isEmpty()) return@filterFast
            showType = 0

            getPermissions(binding.tvTalk)
        }
        binding.tvMap.filterFast {
            if (mViewModel.isChooseCar()) return@filterFast
            showType = 1
            showFragment(showType, binding.tvMap)
        }

        binding.tvDevice.filterFast {
            if (mViewModel.isParamsOk()) return@filterFast
            showType = 2

            showFragment(showType, binding.tvDevice)
        }

        binding.tvController.setOnClickListener {
            if (mViewModel.isParamsOk()) return@setOnClickListener
            showType = 3

            showFragment(showType, binding.tvController)
        }


        binding.tvChannel.filterFast {
            if (mViewModel.isParamsOk()) return@filterFast
            showType = 4

            showFragment(showType, binding.tvChannel)
        }
        binding.tvSetting.filterFast {
            if (mViewModel.isParamsOk()) return@filterFast
            showType = 5

            showFragment(showType, binding.tvSetting)

        }

        binding.ivClose.setOnClickListener {
            if (showType == oldType) {
                oldType = -1
                binding.container.isVisible = false
            }
            mTextView?.isSelected = false
            binding.ivClose.isVisible = false
        }

    }

    private var manager: GridLayoutManager? = null
    private fun initRecycler() {
        manager = GridLayoutManager(this, 1)
        binding.rvVideo.layoutManager = manager
        binding.rvVideo.adapter = mAdapter
    }

    private fun initToolbar() {
        immersionBar { titleBar(binding.mToolbar) }
        ToolbarHelper.setMToolbar(this, getString(R.string.title_monitor_real_video)).setBackClick {
            if (isHome) {
                startHomeActivity()
            } else {
                clearPlayers()
                PlayerManager.clearAllVideo()
                com.syqc.videos.TalkbackUtil.destroy()
                finish()
            }
        }
    }

    private fun initLoadSir() {
        loadService = LoadSir.getDefault().register(binding.rvVideo)
        loadService?.setCallBack(EmptyCallback::class.java) { _, view ->
            val empty = view.findViewById<TextView>(R.id.tv_empty)
            empty.text = getString(R.string.hint_toast_choose_car)
        }
        loadService?.showCallback(EmptyCallback::class.java)

    }

    //处理调转过来的数据
    private fun initIntent() {
        val carId = intent.getStringExtra(Keys.INTENT_CAR_ID)
        if (carId == null) {
            if (NetDataUtil.isSyncTree) {
                launcher.launchAct<TeamsCarsActivity>(this) {
                    putExtra(Keys.INTENT_IS_VIDEO, true)
                }
            } else {
                launcher.launchAct<ChooseCarActivity>(this) {
                    putExtra(Keys.INTENT_IS_VIDEO, true)
                }
            }
            return
        }
        VideoHostUtil.clearHostsClient()
        intent.handleCarInfo()
        binding.lrvChooseCar.isEnabled = false
    }

    //重置车辆相关内容
    private fun resetCar() {
        mViewModel.carId = ""
        mViewModel.clearMap()
        binding.lrvChooseCar.setRightText("")
        mAdapter.setList(null)
        mAdapter.clearPlayer()
        PlayerManager.clearAllVideo()
        loadService?.showCallback(EmptyCallback::class.java)
    }

    private fun clearPlayers() {
        mAdapter?.clearPlayer()
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    private fun getPermissions(radiobutton: TextView) {
        PermissionX.init(this@BasePlayerActivity).permissions(
            Manifest.permission.RECORD_AUDIO
        ).request { allGranted, _, _ ->
            if (allGranted) {
                showFragment(showType, radiobutton)
            } else {

                getString(
                    R.string.toast_persission_open, getString(R.string.permission_audio)
                ).toast(this@BasePlayerActivity)
            }
        }
    }

    private val launcher = registerResultOk { result ->
        result.data?.handleCarInfo(true)

    }

    //处理跳转数据
    private fun Intent.handleCarInfo(isIntent: Boolean = false) {
        val carId = getStringExtra(Keys.INTENT_CAR_ID) ?: ""
        val carName = if (isIntent) {
            getStringExtra(Keys.INTENT_CAR_NAME) ?: ""
        } else {
            getStringExtra(Keys.INTENT_PLATE) ?: ""
        }

        val videos = getStringExtra(Keys.VIDEO) ?: ""

        mViewModel.carId = carId
        mAdapter.carId = mViewModel.carId
        binding.lrvChooseCar.setRightText(carName)

        binding.root.postDelayed({
            mViewModel.isClient(videos)
        }, 100)
    }


    private var isBackground = false

    override fun onPause() {
        super.onPause()
        isBackground = false
        if (!ToolsUtil.isAppOnForeground(this)) {
            isBackground = true
            clearPlayers()
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        clearPlayers()
        currentFragment?.hide()
        PlayerManager.clearAllVideo()
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (PlayerManager.backFromWindowFull(this, mAdapter.getFullKey())) {
                return false
            }
            if (isHome) {
                startHomeActivity()
                return false
            }
            currentFragment?.hide()
        }
        return super.onKeyDown(keyCode, event)
    }

    ////////////////////////////////////////////////////////////////////
    private var currentFragment: BaseRealFragment<*>? = null

    /** 显示Fragment */
    private fun showFragment(fragment: BaseRealFragment<*>) {
        if (currentFragment == fragment) return
        supportFragmentManager.beginTransaction().apply {
            if (currentFragment != null) hide(currentFragment!!)
            currentFragment = fragment
            if (fragment.isAdded) {
                show(fragment)
            } else {
                add(R.id.container, fragment).show(fragment)
            }
        }.commit()
    }

    fun showFragment(type: Int, radiobutton: TextView) {
        currentFragment?.hide()
        oldTextView?.isSelected = false
        if (showType == oldType) {
            oldType = -1
            radiobutton.isSelected = false
            binding.container.isVisible = false
            binding.ivClose.isVisible = false
            return
        }

        radiobutton.isSelected = true
        mTextView = radiobutton
        when (type) {
            0 -> {
                binding.ivClose.isVisible = false
                showFragment(talkFrag)
                binding.root.postDelayed({
                    talkFrag.startRecord(mViewModel.carId, mViewModel.getAudioPass())
                }, 200)
            }

            1 -> {
                binding.ivClose.isVisible = true
                showFragment(getMapFragment())

                binding.root.postDelayed({
                    showMapFragment(mViewModel.carId)
                }, 200)
            }

            2 -> {
                binding.ivClose.isVisible = true
                showFragment(alarmFrag)
                binding.root.postDelayed({
                    alarmFrag.setCarId(mViewModel.carId)
                }, 200)
            }

            3 -> {
                binding.ivClose.isVisible = true
                showFragment(ctrlFrag)
                binding.root.postDelayed({
                    ctrlFrag.setCarId(mViewModel.carId, mViewModel.is28181, mViewModel.controlPass)
                }, 200)
            }

            4 -> {
                binding.ivClose.isVisible = true
                showFragment(channelFrag)
            }

            5 -> {
                binding.ivClose.isVisible = true
                showFragment(settingFrag)
            }
        }
        if (!binding.container.isVisible) binding.container.isVisible = true
        oldType = showType
        oldTextView = radiobutton
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////


    ///////////////////////////////////////////////////////////////////////////////////////////////


    //获取地图fragment
    abstract fun getMapFragment(): BaseRealFragment<*>

    abstract fun showMapFragment(carId: String)

    abstract fun hideMapFragment()
}